Code Appendix
knitr::opts_chunk$set(echo = FALSE)
options(dplyr.summarise.inform=F)
# SPDS
library(tidyverse)
library(sf)
library(units)
library(scales)
# Data
library(USAboundaries)
library(rnaturalearth)
# Visualization
library(gghighlight)
library(ggrepel)
library(knitr)
library(ggthemes)
library(kableExtra)
eqdc = '+proj=eqdc +lat_0=40 +lon_0=-96 +lat_1=20 +lat_2=60 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs'
## USA State Boundaries
nonstate <- c('Puerto Rico', 'Hawaii', 'District of Columbia', 'Alaska')
usstates_raw <- USAboundaries::us_states(resolution = 'low') %>% st_transform(eqdc)
conus <- usstates_raw %>%
filter(!(name %in% nonstate))
conus <- st_transform(conus, eqdc)
## Mexico, Canada, and US Country Borders
country_borders <- countries110 %>% st_as_sf() %>%
filter(admin %in% c('Canada', 'Mexico', 'United States of America')) %>%
st_transform(eqdc)
## Cities
cities <- read_csv('../data/uscities.csv') %>%
st_as_sf(coords = c('lng', 'lat'), crs = 4326) %>%
filter(!(state_name %in% nonstate)) %>%
st_transform(eqdc)
us_boundary <- st_union(usstates_raw) %>%
st_cast('MULTILINESTRING')
city_boundary <- cities %>%
mutate(dist_to_border = st_distance(cities, us_boundary),
dist_to_border = set_units(dist_to_border, 'km'),
dist_to_border = drop_units(dist_to_border))
top_5_border <- city_boundary %>%
slice_max(dist_to_border, n = 5) %>%
select(city, state_name, dist_to_border) %>%
st_set_geometry(NULL)
kable(top_5_border, caption = 'Top 5 Cities by Distance to US Border',
col.names = c('City','State', 'Distance (km)'),
align = 'l',
format.args = list(big.mark = ',')) %>%
kable_styling()
state_boundary <- st_combine(usstates_raw) %>% st_cast('MULTILINESTRING')
state_city_boundary <- cities %>%
mutate(dist_to_border = {st_distance(cities, state_boundary) %>% set_units('km') %>%
drop_units()})
state_top_5_border <- state_city_boundary %>%
slice_max(dist_to_border, n = 5) %>%
select(city, state_name, dist_to_border) %>%
st_set_geometry(NULL)
kable(state_top_5_border, caption = 'Top 5 Cities by Distance to State Border',
col.names = c('City','State', 'Distance (km)'),
align = 'l',
format.args = list(big.mark = ',')) %>%
kable_styling()
mexico_border <- country_borders %>% filter(admin== 'Mexico') %>% st_union() %>% st_cast('MULTILINESTRING')
city_mx_boundary <- cities %>%
mutate(dist_to_mx = {st_distance(cities, mexico_border) %>% set_units('km') %>%
drop_units()})
mx_top_5_border <- city_mx_boundary %>%
slice_max(dist_to_mx, n = 5) %>%
select(city, state_name, dist_to_mx) %>%
st_set_geometry(NULL)
kable(mx_top_5_border, caption = 'Top 5 Cities by Distance to Mexican Border',
col.names = c('City','State', 'Distance (km)'),
align = 'l',
format.args = list(big.mark = ',')) %>%
kable_styling()
canada_border <- country_borders %>% filter(admin== 'Canada') %>% st_union() %>% st_cast('MULTILINESTRING')
city_ca_boundary <- cities %>%
mutate(dist_to_ca = {st_distance(cities, canada_border) %>% set_units('km') %>%
drop_units()})
ca_top_5_border <- city_ca_boundary %>%
slice_max(dist_to_ca, n = 5) %>%
select(city, state_name, dist_to_ca) %>%
st_set_geometry(NULL)
kable(ca_top_5_border, caption = 'Top 5 Cities by Distance to Canadian Border',
col.names = c('City','State', 'Distance (km)'),
align = 'l',
format.args = list(big.mark = ',')) %>%
kable_styling()
big_cities <- cities %>% slice_max(population, n = 10)
top_10_pop <- ggplot() +
geom_sf(data = country_borders) +
geom_sf(data = conus, color = 'red', lty = 2, size = .5) +
geom_sf(data = big_cities, size = 1) +
scale_color_gradient(low = 'grey', high = 'red') +
theme_map() +
geom_label_repel(data = big_cities,
aes(label = city, geometry = geometry),
stat = 'sf_coordinates',
size = 2.75) +
labs('Title Map of Canada, Mexico, US, and top 10 US States by Population')
top_10_pop
top_us_border <- city_boundary %>%
slice_max(dist_to_border, n = 5)
us_border_plot <- ggplot() +
geom_sf(data = conus) +
geom_sf(data = city_boundary, aes(col = dist_to_border), size = .05) +
geom_sf(data = top_us_border)+
scale_color_gradient(low = 'grey', high = 'red') +
theme_map() +
geom_label_repel(data = top_us_border,
aes(label = city, geometry = geometry),
stat = 'sf_coordinates',
size = 2.75) +
labs(col = 'Distance to Border (km)',
title = 'Map of US Cities and Distance to US Border',
subtitle = 'Top 5 Cities by Distance to US Border Labeled')
us_border_plot
state_top_5_geom <- state_city_boundary %>%
slice_max(dist_to_border, n = 5)
state_border_plot <- ggplot() +
geom_sf(data = conus) +
geom_sf(data = state_city_boundary, aes(col = dist_to_border), size = .05) +
geom_sf(data = state_top_5_geom )+
scale_color_gradient(low = 'grey', high = 'red') +
theme_map() +
geom_label_repel(data = state_top_5_geom ,
aes(label = city, geometry = geometry),
stat = 'sf_coordinates',
size = 2.75) +
labs(col = 'Distance to Border (km)',
title = 'Map of US Cities and Distance to State Border',
subtitle = 'Top 5 Cities by Distance to State Border Labeled')
state_border_plot
equi_boundary <- cities %>%
mutate(dist_to_ca = {st_distance(cities, canada_border) %>% set_units('km') %>% drop_units()},
dist_to_mx = {st_distance(cities, mexico_border) %>% set_units('km') %>% drop_units()},
equidistance = {abs(dist_to_ca-dist_to_mx)}
) %>%
filter(equidistance <= 100)
equi_pop <- equi_boundary %>%
slice_max(population, n = 5)
mx_ca_border_plot <- ggplot() +
geom_sf(data = conus) +
geom_sf(data = equi_boundary, size = .05, color = 'darkred', alpha = .4) +
geom_sf(data = equi_pop)+
scale_color_gradient(low = 'grey', high = 'red') +
theme_map() +
geom_label_repel(data = equi_pop ,
aes(label = city, geometry = geometry),
stat = 'sf_coordinates',
size = 2.75) +
labs(col = 'Distance to Border (km)',
title = 'Map of US Cities Equidistant to Canada and Mexico Border ± 100 km',
subtitle = 'Top 5 Cities by Population Labeled')
mx_ca_border_plot
us_border_100 <- city_boundary %>% filter(dist_to_border <= 160)
number_100_mile <- nrow(us_border_100)
population_100_mile <- sum(us_border_100$population)
proportion_100_mile <- population_100_mile/sum(city_boundary$population)
descriptions <- c('Number of cities within the 100-mile zone', 'Population within the 100 mile zone', 'Proportion of population within the 100-mile zone')
values <- c(number_100_mile, population_100_mile, label_percent()(proportion_100_mile))
table <- data.frame(descriptions, values)
kable(table, caption = '100-Mile Zone Facts',
col.names = c('Metric','Value'),
align = 'l',
format.args = list(big.mark = ',')) %>%
kable_styling()
us_border_100 <- city_boundary %>% filter(dist_to_border <= 160)
top_10_per_state <- us_border_100 %>% group_by(state_name) %>% slice_max(population, n = 1)
mile_100_plot <- ggplot() +
geom_sf(data = conus) +
geom_sf(data = city_boundary, aes(col = dist_to_border), size = .05) +
geom_sf(data = top_us_border)+
geom_sf(data = top_10_per_state) +
scale_color_gradient(low = 'orange', high = 'darkred') +
gghighlight(dist_to_border <= 160, unhighlighted_colour = alpha("black", 0.4)) +
geom_label_repel(data = top_10_per_state ,
aes(label = city, geometry = geometry),
stat = 'sf_coordinates',
size = 2.75) +
theme_map() +
labs(title = 'Map of US Cities and 100-Mile Zone',
subtitle = 'Most populous city in each state within the 100-mile zone labeled',
col = 'Distance to \nBorder (km)')+
theme(legend.key.size = unit(0.5, "cm"))
mile_100_plot